
#include <BFont>
#include <BHBoxLayout>
#include <BPainter>

#include "VariantBox.h"

VariantBox::VariantBox(const BString& type, bool editable)
{
	this->setSizePolicy(Policy_Preferred);
	this->setBorder(0);

	BLayout* layout = new BLayout();
	layout->setSizePolicy(Policy_Preferred);
	this->setLayout(layout);

	_intSpinBox = new BSpinBox();
	_longSpinBox = new BLongSpinBox();
	_floatSpinBox = new BFloatSpinBox();
	_doubleSpinBox = new BDoubleSpinBox();
	_stringLineEdit = new BLineEdit();
	_boolCheckBox = new BCheckBox();
	_boolCheckBox->setText("true", true);
	_boolCheckBox->setText("false", false);
	_boolCheckBox->setAlign(Align_Right);

	_intSpinBox->setReadOnly(!editable);
	_longSpinBox->setReadOnly(!editable);
	_floatSpinBox->setReadOnly(!editable);
	_doubleSpinBox->setReadOnly(!editable);
	_stringLineEdit->setReadOnly(!editable);

	connect(this, Signal_Renamed, &VariantBox::slotNameChanged);
	connect(_boolCheckBox, Signal_Checked, &VariantBox::slotBoolChecked);
	connect(_intSpinBox, Signal_ValueChanged, &VariantBox::slotIntValueChanged);
	connect(_longSpinBox, Signal_ValueChanged, &VariantBox::slotLongValueChanged);
	connect(_floatSpinBox, Signal_ValueChanged, &VariantBox::slotFloatValueChanged);
	connect(_doubleSpinBox, Signal_ValueChanged, &VariantBox::slotDoubleValueChanged);
	connect(_stringLineEdit, Signal_EditFinished, &VariantBox::slotStringEditFinished);

	setType(type);
}
VariantBox::~VariantBox()
{

}

void VariantBox::setType(const BString& type)
{
	if (_variant.type != type)
	{
		_variant.type = (type);
		BLayout* layout = this->layout();
		layout->remove(_boolCheckBox);
		layout->remove(_intSpinBox);
		layout->remove(_longSpinBox);
		layout->remove(_floatSpinBox);
		layout->remove(_doubleSpinBox);
		layout->remove(_stringLineEdit);
		if (type == "bool")
		{
			layout->setWidget(_boolCheckBox);
			_variant.value = (_boolCheckBox->checked());
		}
		else if (type == "int")
		{
			layout->setWidget(_intSpinBox);
			_variant.value = (_intSpinBox->value());
		}
		else if (type == "long")
		{
			layout->setWidget(_longSpinBox);
			_variant.value = (_longSpinBox->value());
		}
		else if (type == "float")
		{
			layout->setWidget(_floatSpinBox);
			_variant.value = (_floatSpinBox->value());
		}
		else if (type == "double")
		{
			layout->setWidget(_doubleSpinBox);
			_variant.value = (_doubleSpinBox->value());
		}
		else if (type == "string")
		{
			layout->setWidget(_stringLineEdit);
			_variant.value = (_stringLineEdit->text());
		}
		else
		{
			_variant.value = (BValue());
		}
	}
}
const BString& VariantBox::type() const
{
	return _variant.type;
}

void VariantBox::setVariant(const Variant& variant)
{
	if (_variant.type != variant.type)
	{
		setType(variant.type);
	}
	_variant = variant;
}
const Variant& VariantBox::variant() const
{
	return _variant;
}

void VariantBox::setValue(const BValue& value)
{
	_variant.value = value;
}
const BValue& VariantBox::value() const
{
	return _variant.value;
}

void VariantBox::refresh()
{
	if (_variant.type == "bool")
		_boolCheckBox->setChecked(_variant.value);
	else if (_variant.type == "int")
		_intSpinBox->setValue(_variant.value);
	else if (_variant.type == "long")
		_longSpinBox->setValue(_variant.value);
	else if (_variant.type == "float")
		_floatSpinBox->setValue(_variant.value);
	else if (_variant.type == "double")
		_doubleSpinBox->setValue(_variant.value);
	else if (_variant.type == "string")
		_stringLineEdit->setText(_variant.value);
}

void VariantBox::slotNameChanged(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
void VariantBox::slotBoolChecked(BObject* object, const BValue& value)
{
	bool checked = value;
	_variant.value = (value);
}
void VariantBox::slotIntValueChanged(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
void VariantBox::slotLongValueChanged(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
void VariantBox::slotFloatValueChanged(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
void VariantBox::slotDoubleValueChanged(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
void VariantBox::slotStringEditFinished(BObject* object, const BValue& value)
{
	_variant.value = (value);
}
